#include "draw.h"
#include "terminal.h"
#include "utils.h"
#include "control.h"
namespace dw
{   
    void window(int top, int left, int width, int height, std::string title, std::u32string style)
    {
        std::ostringstream oss;
        //draw variable frame
        /* for(int r=0; r<height; ++r)
        {
            tc::move_to(top+r, ut::b2c(left), oss);
            for(int c=0; c<width; ++c)
            {
                if(r==0)
                {
                    if(c==0)
                    {
                        oss<<ut::utf32_to_utf8({style[0],style[1]});
                    }
                    else if(c==width-1)
                    {
                        oss<<ut::utf32_to_utf8({style[2]});
                    }
                    else
                    {
                        oss<<ut::utf32_to_utf8({style[6],style[6]});
                    }
                }
                else if(r==height-1)
                {
                    if(c==0)
                    {
                        oss<<ut::utf32_to_utf8({style[0],style[3]});
                    }
                    else if(c==width-1)
                    {
                        oss<<ut::utf32_to_utf8({style[4]});
                    }
                    else
                    {
                        oss<<ut::utf32_to_utf8({style[6],style[6]});
                    }
                }
                else
                {
                    if(c==0)
                    {
                        oss<<ut::utf32_to_utf8({style[0],style[5]});
                    }
                    else if(c==width-1)
                    {
                        oss<<ut::utf32_to_utf8({style[5]});
                    }
                    else
                    {
                        oss<<ut::utf32_to_utf8({style[0],style[0]});
                    }
                }
            }
        } */

        for (int c=0; c<width; ++c)
        {
            tc::move_to(top, ut::b2c(left+c), oss);
            if(c==0)
            {
                oss<<ut::utf32_to_utf8({style[0],style[1]});
                tc::move_to(top+height-1, ut::b2c(left+c), oss);
                oss<<ut::utf32_to_utf8({style[0],style[3]});
            }
            else if(c==width-1)
            {
                oss<<ut::utf32_to_utf8({style[2]});
                tc::move_to(top+height-1, ut::b2c(left+c), oss);
                oss<<ut::utf32_to_utf8({style[4]});
            }
            else
            {
                oss<<ut::utf32_to_utf8({style[6],style[6]});
                tc::move_to(top+height-1, ut::b2c(left+c), oss);
                oss<<ut::utf32_to_utf8({style[6],style[6]});
            }
        }
        for(int r=1; r<height-1; ++r)
        {
            tc::move_to(top+r, ut::b2c(left), oss);
            oss<<ut::utf32_to_utf8({style[0],style[5]});
            tc::move_to(top+r, ut::b2c(left+width-1), oss);
            oss<<ut::utf32_to_utf8({style[5]});
        }

        //draw title
        tc::move_to(top, ut::b2c(left)+(width*2-title.length())/2, oss);
        oss << title;

        std::cout << oss.str();
    }

    // void tetromino(Tetromino &t, int top, int left, int index)
    // {
    //     tc::move_to(top, ut::b2c(left));
    //     tc::set_back_color((int)t[index][0].second);   
    //     std::cout<<"  ";
    //     for(auto p : t[index])
    //     {
    //         if(p.first > 'A') continue;
    //         tc::move_to(top-p.second, ut::b2c(left+p.first));
    //         std::cout<<"  ";
    //     }
    // }

    void frame(Matrix &frame, int top, int left)
    {
        static Matrix buffer(frame.size(), std::vector<int>(frame[0].size(), -1));
        std::ostringstream oss;

        int row, col;
        for (int x = 0; x < 10; ++x)
        {
            for (int y = 0; y < 20; ++y)
            {
                if(buffer[x][y] == frame[x][y]) continue;
                buffer[x][y] = frame[x][y];

                row = top + 20 - y - 1;
                col = left + x;
                tc::move_to(row, ut::b2c(col), oss);
                if(frame[x][y] > 0)    //普通块
                {
                    tc::reset_color(oss);
                    tc::set_back_color(frame[x][y], oss);
                    oss << "  ";
                }
                else if(frame[x][y] < 0)    //阴影块
                {
                    tc::reset_color(oss);
                    tc::set_fore_color(0 - frame[x][y], oss);
                    oss << "\u25e3\u25e5";
                }
                else
                {
                    tc::reset_color(oss);
                    oss << "\u30FB";
                }
            }
        }
        std::cout<<oss.str();
    }

    void data(int top, int left, int score,int lines,int level)
    {
        std::ostringstream oss;
        static int col = 2;

        tc::reset_color(oss);
        tc::move_to(top + 3, left + col, oss);
        oss << "level: " << level;
        tc::move_to(top + 4, left + col, oss);
        oss << "lines: " << lines;
        tc::move_to(top + 5, left + col, oss);
        oss << "Score: " << score;
        tc::move_to(top + 7, left + col, oss); 
        oss << "FPS: " << ut::fps();
        tc::move_to(top + 8, left + col, oss);
        oss << "Time: " << std::setprecision(2) << std::setiosflags(std::ios::fixed) << ut::time();
        tc::move_to(top + 9, left + col, oss);
        oss << "CMD: "<< gm::get_keyid();
        std::cout<<oss.str();
    }

    void next(Matrix &n, int top, int left)
    {
        std::ostringstream oss;
        int row, col;
        for(int x = 0; x < 6; x++)
        {
            for(int y = 0; y < 16; y++)
            {
                row = top + 16 - y - 1;
                col = left + x;
                tc::move_to(row, ut::b2c(col), oss);
                tc::reset_color(oss);
                if(n[x][y]>0)
                {
                    tc::set_back_color(n[x][y], oss);
                    oss << "  ";
                }
                else
                {
                    oss << "  ";
                }
            }
        }

        std::cout << oss.str();
    }

    void hole(Matrix &holdPiece, int top, int left)
    {
        std::ostringstream oss;
        int row, col;
        for(int x = 0; x < 7; x++)
        {
            for(int y = 0; y < 4; y++)
            {
                row = top + 4 - y - 1;
                col = left + x;
                tc::move_to(row, ut::b2c(col), oss);
                tc::reset_color(oss);
                if(holdPiece[x][y]>0)
                {
                    tc::set_back_color(holdPiece[x][y], oss);
                    oss << "  ";
                }
                else
                {
                    oss << "  ";
                }
            }
        }

        std::cout << oss.str();

    }

    void losed(int top, int left)
    {
        std::string msg = "You losed!";
        std::ostringstream oss;
        tc::move_to(left, ut::b2c(left)+(12 * 2 - msg.length()) / 2, oss);
        tc::reset_color(oss);
        tc::set_fore_color((int)Color::Red, oss);
        oss << msg;
        std::cout << oss.str();
    }

    void help()
    {
        int row=11;
        std::ostringstream oss;

        tc::reset_color();
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"旋转: 空格键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"左移: a 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"右移: d 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"下移: s 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"旋转: w 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"Hold: r 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"急降: 空格键"; 
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"帮助: h 键";
        tc::move_to(row++,ut::b2c(30),oss);
        oss<<"退出: q 键";

        std::cout << oss.str();
    
    }

}